﻿using System;
using System.Collections;
using System.Configuration;
using System.IO;
using System.Data;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml;
using Microsoft.Win32;


namespace icrmGridActions
{
  public partial class SingleGridAction : System.Web.UI.Page
  {
    private const string UPDATE = "Update";
    private string orgname;
    private string crmurl;
    private string metaurl;
    private bool offline;

    protected void Page_Load(object sender, EventArgs e)
    {
      string ServerUrl = "";
      if (string.Compare(Request.QueryString["sState"], UPDATE, true) == 0)
      {

        #region CRM URLs and Organization Name
        //Determine Offline State from Host Name
        if (Request.Url.Host.ToString() == "127.0.0.1")
        {
          offline = true;

          //Retrieve the Port and OrgName from the Registry
          RegistryKey regkey = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\MSCRMClient");
          orgname = regkey.GetValue("ClientAuthOrganizationName").ToString();
          string portnumber = regkey.GetValue("CassiniPort").ToString();

          //Construct the URLs
          string baseurl = "http://localhost:" + portnumber + "/mscrmservices/2007/";
          crmurl = String.Format("{0}crmservice.asmx", baseurl);
          metaurl = baseurl + "metadataservice.asmx";
        }
        else
        {
          offline = false;

          //Retrieve the URLs from the Registry
          RegistryKey regkey = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\MSCRM");
          ServerUrl = regkey.GetValue("ServerUrl").ToString();
          crmurl = String.Format("{0}/2007/crmservice.asmx", ServerUrl);
          metaurl = ServerUrl + "/2007/metadataservice.asmx";
          //Retrieve the Query String from the current URL
          if (Request.QueryString["orgname"] == null)
          {
            orgname = string.Empty;
          }
          else
          {
            //Query String
            string orgquerystring = Request.QueryString["orgname"].ToString();
            if (string.IsNullOrEmpty(orgquerystring))
            {
              orgname = string.Empty;
            }
            else
            {
              orgname = orgquerystring;
            }
          }

          if (string.IsNullOrEmpty(orgname))
          {
            //Windows Auth URL
            if (Request.Url.Segments[2].TrimEnd('/').ToLower() == "isv")
            {
              orgname = Request.Url.Segments[1].TrimEnd('/').ToLower();
            }

            //IFD URL
            if (string.IsNullOrEmpty(orgname))
            {
              string url = Request.Url.ToString().ToLower();
              int start = url.IndexOf("://") + 3;
              orgname = url.Substring(start, url.IndexOf(".") - start);
            }
          }
        }
        #endregion


        Response.ContentType = "text/xml";
        Response.Clear();
        try
        {
          // string orgname = Request.QueryString["orgname"];
          string sAction = Request.QueryString["action"];
          sAction = sAction.ToUpper();
          crmActions action = new crmActions(offline, orgname, crmurl, Request.Url, Context);

          // Get the list of records that are selected in the grid.
          string[] selectedEntities = GetSelectedEntities();
          if (selectedEntities.Length > 0)
          {
            // Set a GUID to the first ID in the string array.
            System.Guid idGuid = new System.Guid(selectedEntities[0]);
            string url = "";
            //Action switch create a new case for any new action that you want to take.
            //Then create the action method in the crmAction class.
            switch (sAction)
            {
              case "PRIMARY_CONTACT":
                action.SetContactAsPrimary(idGuid);
                break;
              case "PHONECALL_CONTACT":
                url = action.GetNewPhone_Contact(idGuid);
                Response.Write(GetXMLNodeText("returnurl", url));
                break;
              case "TASK_CONTACT":
                url = action.GetNewTask_Contact(idGuid);
                Response.Write(GetXMLNodeText("returnurl", url));
                break;
              case "EMAIL_CONTACT":
                url = action.GetNewEmail_Contact(idGuid);
                Response.Write(GetXMLNodeText("returnurl", url));
                break;
              case "CASE_CONTACT":
                url = action.GetNewCase_Contact(idGuid);
                Response.Write(GetXMLNodeText("returnurl", url));
                break;
              case "PHONECALL_OPP":
                url = action.GetNewPhone_Opp(idGuid);
                Response.Write(GetXMLNodeText("returnurl", url));
                break;
              case "PHONECALL_ACCOUNT":
                url = action.GetNewPhone_Account(idGuid);
                Response.Write(GetXMLNodeText("returnurl", url));
                break;
              default:
                throw new Exception("invalid action parameter");
            }
          }
        }
        catch (System.Web.Services.Protocols.SoapException ex)
        {
          //Response.Write("<error>");
          //Response.Write(
          //         "An error occurred while accessing Microsoft CRM.");
          //Response.Write(ex.Detail.OuterXml.ToString());
          //Response.Write("</error>");
          string errMsg = String.Format("{1}\n{2}\n{3}\n{4}\nAn error occurred while accessing Microsoft CRM.\n{0}", ex.Detail.OuterXml.ToString(), crmurl, orgname, Request.Url.AbsoluteUri, Request.Url.ToString());
          Response.Write(GetXMLNodeText("error", errMsg));
        }
        catch (System.Exception ex)
        {
          //Response.Write("<error>");
          //Response.Write(ex.Message);
          //Response.Write("</error>");
          Response.Write(GetXMLNodeText("error", ex.Message));
        }
        finally
        {
          // Add a tag to identify the end of the message.
          Response.Write("<eom />");
          Response.Flush();
        }
      }
    }

    private string GetXMLNodeText(string nodeName, string value)
    {
      //Set the string to return as an XML Node
      XmlDocument xml = new XmlDocument();
      XmlElement nodeText = xml.CreateElement(nodeName);
      nodeText.InnerText = value;
      xml.AppendChild(nodeText);
      return xml.InnerXml;
    }

    private string[] GetSelectedEntities()
    {
      // Read the Xml data that is passed in the HttpRequest stream.
      StreamReader sr = new StreamReader(Request.InputStream);
      string recordIds = sr.ReadToEnd();

      // Load the data string into an Xml document. The list of comma separated
      // IDs are obtained from the document element InnerText.
      XmlDocument xmlDoc = new XmlDocument();
      xmlDoc.LoadXml(recordIds);
      string selectedEntities = xmlDoc.DocumentElement.InnerText;

      // If the string is empty, no entities have been selected by the user.
      if (selectedEntities == null || selectedEntities.Length == 0)
      {
        return new string[0];
      }

      // Split the string of comma separated IDs into an array.
      return selectedEntities.Split(new char[] { ',' });
    }
  }
}